package com.study.basic

import org.apache.spark.mllib.stat.KernelDensity
import org.apache.spark.sql.SparkSession

/**
 * 核密度估计
 * Kernel density estimation
 * 根据已知的样本估计未知的密度，属于非参数检验方法之一。
 *
 * @author stephen
 * @date 2019-08-27 14:30
 */
object KernelDensityWEstimationDemo {

  def main(args: Array[String]): Unit = {
    val spark = SparkSession.builder()
      .appName(this.getClass.getSimpleName)
      .master("local[*]")
      .getOrCreate()

    spark.sparkContext.setLogLevel("warn")

    val path = this.getClass.getClassLoader.getResource("data/iris.data").getPath
    val test = spark.sparkContext.textFile(path).map(_.split(",")).map(p => p(0).toDouble)

    // 用样本数据构建核函数，这里用假设检验中得到的iris的第一个属性的数据作为样本数据进行估计
    // setBandwidth表示高斯核的宽度，为一个平滑参数，可以看做是高斯核的标准差
    val kd = new KernelDensity().setSample(test).setBandwidth(3.0)
    // 构造了核密度估计kd，就可以对给定数据数据进行核估计
    val densities = kd.estimate(Array(-1.0, 2.0, 5.0, 5.8))
    // 在样本-1.0, 2.0, 5.0, 5.8等样本点上，其估算的概率密度函数值分别是0.011372003554433524, 0.059925911357198915, 0.12365409462424519, 0.12816280708978114
    println(densities.toList)

    spark.stop()
  }
}
